package com.powernode.driver.service.impl;


import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.common.constant.SystemConstant;
import com.powernode.driver.config.TencentProperties;
import com.powernode.driver.mapper.*;
import com.powernode.driver.service.CosService;
import com.powernode.driver.service.DriverInfoService;
import com.powernode.model.entity.driver.*;
import com.powernode.model.form.driver.DriverFaceModelForm;
import com.powernode.model.form.driver.UpdateDriverAuthInfoForm;
import com.powernode.model.vo.driver.DriverAuthInfoVo;
import com.powernode.model.vo.driver.DriverInfoVo;
import com.powernode.model.vo.driver.DriverLoginVo;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonRequest;
import com.tencentcloudapi.iai.v20180301.models.CreatePersonResponse;
import com.tencentcloudapi.iai.v20180301.models.VerifyFaceRequest;
import com.tencentcloudapi.iai.v20180301.models.VerifyFaceResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class DriverInfoServiceImpl extends ServiceImpl<DriverInfoMapper, DriverInfo> implements DriverInfoService {

    @Resource
    private WxMaService wxMaService;

    @Resource
    private DriverSetMapper driverSetMapper;

    @Resource
    private DriverAccountMapper accountMapper;
    @Resource
    private DriverAccountMapper driverAccountMapper;
    @Resource
    private DriverLoginLogMapper driverLoginLogMapper;

    @Resource
    private CosService cosService;

    @Resource
    private TencentProperties tencentProperties;


    @Resource
    private DriverFaceRecognitionMapper driverFaceRecognitionMapper;

    /**
     * 配送员登录
     * 1.获取用户的微信openId
     * 2.根据openId查询用户
     * 3.若用户不存在，则插入用户信息 driver_info
     * 4.初始化配送员默认接单数据 driver_set表
     * 5.初始化配送员账户信息 driver_account表
     * 6.记录日志
     */
    @Transactional
    @Override
    public Long login(String code) {
        DriverInfo driverInfo = null;
        try {
            //1.获取用户的微信openId
            WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
            String openid = sessionInfo.getOpenid();

            //2.根据openId查询用户
            driverInfo = getOne(new LambdaQueryWrapper<DriverInfo>().eq(DriverInfo::getWxOpenId, openid));

            //3.若用户不存在，则插入用户信息 driver_info
            if (driverInfo == null) {
                driverInfo = new DriverInfo();
                driverInfo.setWxOpenId(openid);
                driverInfo.setCreateTime(new Date());
                driverInfo.setNickname("laoDu");
                save(driverInfo);

                //4.初始化配送员默认接单数据 driver_set表
                DriverSet driverSet = new DriverSet();
                driverSet.setDriverId(driverInfo.getId());
                driverSet.setCreateTime(new Date());
                driverSet.setAcceptDistance(new BigDecimal(SystemConstant.ACCEPT_DISTANCE));
                driverSet.setOrderDistance(BigDecimal.ZERO);
                driverSet.setServiceStatus(0);
                driverSet.setIsAutoAccept(0);

                driverSetMapper.insert(driverSet);


                //5.初始化配送员账户信息 driver_account表
                DriverAccount driverAccount = new DriverAccount();
                driverAccount.setDriverId(driverInfo.getId());
                driverAccountMapper.insert(driverAccount);
            }

            //6.记录日志
            DriverLoginLog driverLoginLog = new DriverLoginLog();
            driverLoginLog.setDriverId(driverInfo.getId());
            driverLoginLog.setMsg("小程序登录");

            driverLoginLogMapper.insert(driverLoginLog);


        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }

        return driverInfo.getId();
    }


    /**
     * 获取配送员信息
     */
    @Override
    public DriverLoginVo getDriverLoginInfo(Long driverId) {
        //根据主键查询配送员信息
        DriverInfo driverInfo = getById(driverId);
        DriverLoginVo driverLoginVo = new DriverLoginVo();

        BeanUtils.copyProperties(driverInfo, driverLoginVo);

        //是否建立人脸模型
        driverLoginVo.setIsArchiveFace(driverInfo.getFaceModelId() != null);

        return driverLoginVo;
    }

    /**
     * 获取配送员认证信息
     */
    @Override
    public DriverAuthInfoVo getDriverAuthInfo(Long driverId) {
        DriverInfo driverInfo = getById(driverId);
        DriverAuthInfoVo driverAuthInfoVo = new DriverAuthInfoVo();
        BeanUtils.copyProperties(driverInfo, driverAuthInfoVo);

        //主键
        driverAuthInfoVo.setDriverId(driverInfo.getId());

        driverAuthInfoVo.setIdcardBackShowUrl(cosService.getImageUrl(driverInfo.getIdcardBackUrl()));
        driverAuthInfoVo.setIdcardFrontShowUrl(cosService.getImageUrl(driverInfo.getIdcardFrontUrl()));
        driverAuthInfoVo.setIdcardHandShowUrl(cosService.getImageUrl(driverInfo.getIdcardHandUrl()));

        return driverAuthInfoVo;
    }


    /**
     * 修改配送员认证信息
     */
    @Transactional
    @Override
    public Boolean updateDriverAuthInfo(UpdateDriverAuthInfoForm updateDriverAuthInfoForm) {
        DriverInfo driverInfo = new DriverInfo();
        driverInfo.setId(updateDriverAuthInfoForm.getDriverId());
        BeanUtils.copyProperties(updateDriverAuthInfoForm, driverInfo);

        return updateById(driverInfo);
    }

    /**
     * 构建配送员人脸库
     */
    @Override
    public Boolean createDriverFaceModel(DriverFaceModelForm driverFaceModelForm) {

        //根据id查询配送员信息
        DriverInfo driverInfo = getById(driverFaceModelForm.getDriverId());

        //构建凭证
        Credential credential = new Credential(tencentProperties.getSecretId(), tencentProperties.getSecretKey());

        //构建请求对象
        CreatePersonRequest req = new CreatePersonRequest();
        req.setGroupId(tencentProperties.getPersionGroupId());//配送员人脸库
        req.setPersonId(driverInfo.getId().toString());
        req.setGender(Long.parseLong(driverInfo.getGender()));
        req.setQualityControl(4L);//图片质量要求
        req.setUniquePersonControl(4L);//误判的概率
        req.setPersonName(driverInfo.getName());
        req.setImage(driverFaceModelForm.getImageBase64());//传入图片的base64文本


        try {
            //发送请求 获取响应
            CreatePersonResponse resp = new IaiClient(credential, tencentProperties.getRegion()).CreatePerson(req);

            //人脸id
            String faceId = resp.getFaceId();
            //将人脸id更新到数据库中
            driverInfo.setFaceModelId(faceId);
            updateById(driverInfo);
            return true;
        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 获取配送员个性化设置
     */
    @Override
    public DriverSet getDriverSet(Long driverId) {
        LambdaQueryWrapper<DriverSet> queryWrapper = new LambdaQueryWrapper<DriverSet>()
                .eq(DriverSet::getDriverId, driverId);

        return driverSetMapper.selectOne(queryWrapper);
    }


    /**
     * 查看配送员当天是否进行人脸识别
     */
    @Override
    public Boolean isFaceIdentify(Long driverId) {
        LambdaQueryWrapper<DriverFaceRecognition> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(DriverFaceRecognition::getDriverId, driverId);

        //查询当天
        queryWrapper.ge(DriverFaceRecognition::getFaceDate, new DateTime().toString("yyyy-MM-dd"));

        Long count = driverFaceRecognitionMapper.selectCount(queryWrapper);

        return count > 0;
    }

    /**
     * 人脸验证
     */
    @Override
    public Boolean verifyDriverFace(DriverFaceModelForm driverFaceModelForm) {


        try {
            Credential cred = new Credential(tencentProperties.getSecretId(), tencentProperties.getSecretKey());

            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("iai.tencentcloudapi.com");

            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);

            IaiClient iaiClient = new IaiClient(cred, tencentProperties.getRegion(), clientProfile);

            //构建人脸识别请求
            VerifyFaceRequest faceRequest = new VerifyFaceRequest();

            faceRequest.setPersonId(driverFaceModelForm.getDriverId().toString());
            faceRequest.setImage(driverFaceModelForm.getImageBase64());

            //获取响应
            VerifyFaceResponse faceResponse = iaiClient.VerifyFace(faceRequest);

            if (faceResponse.getIsMatch()) {

                //保存当天配送员的人脸识别信息
                DriverFaceRecognition driverFaceRecognition = new DriverFaceRecognition();
                driverFaceRecognition.setDriverId(driverFaceModelForm.getDriverId());
                driverFaceRecognition.setFaceDate(new Date());

                driverFaceRecognitionMapper.insert(driverFaceRecognition);

                return true;
            }


        } catch (TencentCloudSDKException e) {
            throw new RuntimeException(e);
        }

        return false;
    }


    /**
     * 修改配送员接单状态   上下班
     */
    @Override
    public Boolean updateDriverWorkStatus(Long driverId, Integer status) {
        LambdaQueryWrapper<DriverSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DriverSet::getDriverId, driverId);

        DriverSet driverSet = new DriverSet();
        driverSet.setServiceStatus(status);//0 下班  1 上班

        return driverSetMapper.update(driverSet, queryWrapper) > 0;
    }

    /**
     * 获取配送员信息
     */
    @Override
    public DriverInfoVo getDriverInfo(Long driverId) {
        DriverInfo driverInfo = getById(driverId);

        DriverInfoVo driverInfoVo = new DriverInfoVo();
        BeanUtils.copyProperties(driverInfo, driverInfoVo);


        //我们没有上传驾照，这里写死驾龄
        driverInfoVo.setDriverLicenseAge(5);

        return driverInfoVo;
    }
}